/*
 *
 *  * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 *
 *
 */

package com.iwindplus.base.alert.service.impl;

import cn.hutool.core.text.CharSequenceUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.iwindplus.base.domain.constant.CommonConstant.ExceptionConstant;
import com.iwindplus.base.domain.enums.BizCodeEnum;
import com.iwindplus.base.domain.exception.BizException;
import com.iwindplus.base.http.client.manager.RestClientManager;
import com.iwindplus.base.alert.domain.constant.AlertConstant.FeishuConstant;
import com.iwindplus.base.alert.service.AlertFeishuService;
import com.iwindplus.base.util.JacksonUtil;
import com.lark.oapi.Client;
import com.lark.oapi.core.enums.AppType;
import com.lark.oapi.service.im.v1.enums.CreateMessageReceiveIdTypeEnum;
import com.lark.oapi.service.im.v1.enums.MsgTypeEnum;
import com.lark.oapi.service.im.v1.model.CreateMessageReq;
import com.lark.oapi.service.im.v1.model.CreateMessageReqBody;
import com.lark.oapi.service.im.v1.model.CreateMessageResp;
import jakarta.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;

/**
 * 飞书告警相关业务层接口实现类.
 *
 * @author zengdegui
 * @since 2025/11/30 21:47
 */
@Slf4j
public class AlertFeishuServiceImpl extends AbstractAlertBaseServiceImpl implements AlertFeishuService {

    @Resource
    private RestClientManager restClientManager;

    @Override
    public boolean sendAlertMsg(String receiveId, String content) {
        return this.sendPersonMsgByApp(CreateMessageReceiveIdTypeEnum.USER_ID, MsgTypeEnum.MSG_TYPE_TEXT, receiveId, content);
    }

    @Override
    public boolean sendWebhookMsg(String webhook, MsgTypeEnum msgType, String content, String secret) {
        final Map<String, Object> map = new HashMap<>(16);
        map.put(FeishuConstant.MSG_TYPE, msgType.getValue());
        map.put(FeishuConstant.CONTENT, content);
        if (CharSequenceUtil.isNotBlank(secret)) {
            long timestamp = Instant.now().getEpochSecond();
            String sign = genSign(timestamp, secret);
            map.put(FeishuConstant.TIMESTAMP, String.valueOf(timestamp));
            map.put(FeishuConstant.SIGN, sign);
        }

        String body = JacksonUtil.toJsonStr(map);

        final String data = this.restClientManager.httpPostByJson(webhook, null, body, String.class, false);
        log.info("飞书webhook发送结果：{}", data);
        if (CharSequenceUtil.isNotBlank(data)) {
            JsonNode jsonNode = JacksonUtil.parseTree(data);
            int vo = jsonNode.get(FeishuConstant.RESPONSE_CODE).asInt();
            if (vo == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 发送飞书消息（企业自建应用）.
     *
     * @param receiveId 接收人ID
     * @param content   消息内容
     * @return boolean
     */
    private boolean sendPersonMsgByApp(CreateMessageReceiveIdTypeEnum receiveIdType, MsgTypeEnum msgType, String receiveId, String content) {
        final Client client = getClient();
        final CreateMessageReq req = CreateMessageReq.newBuilder()
            .receiveIdType(Optional.ofNullable(receiveIdType).orElse(CreateMessageReceiveIdTypeEnum.OPEN_ID))
            .createMessageReqBody(CreateMessageReqBody.newBuilder()
                .receiveId(receiveId)
                .msgType(Optional.ofNullable(msgType).map(MsgTypeEnum::getValue).orElse(MsgTypeEnum.MSG_TYPE_TEXT.getValue()))
                .content(content)
                .build())
            .build();
        try {
            final CreateMessageResp resp = client.im().message().create(req);
            if (resp != null && resp.success()) {
                return true;
            }
            log.info("发送飞书消息（企业自建应用）发送结果：{}", resp.getMsg());
        } catch (Exception ex) {
            log.error(ExceptionConstant.EXCEPTION, ex);

            throw new BizException(BizCodeEnum.SEND_ERROR);
        }
        return false;
    }

    private Client getClient() {
        return Client.newBuilder(this.getConfig().getFeishu().getAppId(),
                this.getConfig().getFeishu().getAppSecret())
            .appType(AppType.SELF_BUILT)
            .build();
    }

    private static String genSign(long timestamp, String secret) {
        String algorithm = "HmacSHA256";
        try {
            String toSign = CharSequenceUtil.format("{}\n{}", timestamp, secret);

            Mac mac = Mac.getInstance(algorithm);
            mac.init(new SecretKeySpec(toSign.getBytes(StandardCharsets.UTF_8), algorithm));
            byte[] signData = mac.doFinal(new byte[0]);
            return Base64.getEncoder().encodeToString(signData);
        } catch (Exception e) {
            log.error(ExceptionConstant.EXCEPTION, e);

            throw new BizException(BizCodeEnum.INVALID_SIGN);
        }
    }
}
